package com.joker.airoleplayplatformback.config;

import com.joker.airoleplayplatformback.domain.po.UserPO;
import com.joker.airoleplayplatformback.service.UserService;
import com.joker.airoleplayplatformback.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

/**
 * JWT 认证过滤器
 * @author feixiang.li
 * @since 2025-09-27
 */
@Slf4j
public class JWTAuthenticationFilter extends OncePerRequestFilter {


    private final String TOKEN_PREFIX = "Bearer ";
    private final String HEADER_STRING = "Authorization";

    private final UserService userService;

    private final JwtUtils jwtUtils;


    public JWTAuthenticationFilter(UserService userService, JwtUtils jwtUtils) {
        this.userService = userService;
        this.jwtUtils = jwtUtils;
    }


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String token = getTokenFromRequest(request);

        if (token != null && !jwtUtils.isTokenExpired(token)) {
            Long userId = jwtUtils.getUserIdFromToken(token);
            log.info("用户 {} 的 Token", userId);
            // 根据 token 中的用户名加载用户详细信息
            UserPO byId = userService.findById(userId);
            if (byId == null) {
                return;
            }
            UserDetails userDetails = User.builder().username(byId.getUsername()).password(byId.getPassword()).build();

            // 根据 token 创建一个 Authentication 对象并设置到 SecurityContext
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        // 继续过滤请求
        filterChain.doFilter(request, response);
    }

    // 从请求头中提取 Token
    private String getTokenFromRequest(HttpServletRequest request) {
        String header = request.getHeader(HEADER_STRING);
        if (header != null && header.startsWith(TOKEN_PREFIX)) {
            return header.substring(TOKEN_PREFIX.length());
        }
        return null;
    }
}